#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>

#include "socket.h"
#include "load.pb.h"
#include "structures.h"

using namespace std;

#define SLEEP_TIME 5


void read_config(const char *file, char *ip, char *port)
{
	FILE *config;
	size_t size = 255;
	char *ind;

	if ((config = fopen(file, "r")) == NULL) {
		perror("Config file:");
		exit(1);
	}

	getline(&ip, &size, config);

	getline(&port, &size, config);
	string s1, s2;

	printf("IP: %s\n", ip);
	printf("Port: %s\n", port);

	ind = rindex( ip, '\n');
	if (ind)
		ind = '\0';

	ind = rindex( port, '\n');
	if (ind)
		ind = '\0';
}

int main(int argc, char **argv)
{
	int sockfd, fd;
	struct sockaddr_in servaddr;
	char *arg, *ip, *port ;
	Load info;
	uint32_t req_id = slave_load;
	int flag = 1, count = 0;
	size_t size = 20;
	FILE *cmd;
	string loadInfo;

	Socket *s = new Socket();

	arg = new char[20];
	ip = new char[255];
	port = new char[255]
	                ;
	string temp("./server_config");
	const char *file = temp.c_str();

	read_config(file, ip, port);

	//hostent* record = gethostbyname(ip);
	//in_addr* address=(in_addr * )record->h_addr;

	//TODO: Remove the truth from the condition below

	if (!s->Create()) {
		cerr << " Error creating " << endl;
		exit(1);
	}
	short unsigned int p = (short unsigned int) atoi(port);
	//cout << ip << endl;
	//cout << port << endl;
	char *ind;
	ind = rindex( ip, '\n');
	if (ind)
		ind = '\0';
	cout << ip << endl;
	if(s->Connect("172.22.28.75", p)){
		/*Periodically send load information to the server
		 * Later, we can send information on events such as
		 * "compilation ended"
		 */
		while(1) {
			cmd = popen("./estats.sh", "r");

			getline(&arg, &size, cmd);
			info.set_idle_perc(atof(arg));

			getline(&arg, &size, cmd);
			info.set_rps(atof(arg));

			getline(&arg, &size, cmd);
			info.set_wps(atof(arg));

			pclose(cmd);

			cmd = popen("./ip.sh", "r");
			getline(&arg, &size, cmd);

			info.set_ip(string(arg));

			cout << "Idle time: " << info.idle_perc() << endl;
			cout << "R/sec: " << info.rps() << endl;
			cout << "W/sec: " << info.wps() << endl;
			cout << "IP: " << info.ip() << endl;


			if (count == 0) {
				//We send request_id only once (to establish our identity)
				cout << "Sending req_id: " << req_id <<", size: " << sizeof(req_id) << endl;
				s->Send((void *)&req_id, sizeof(req_id));
				count++;
			}

			info.SerializeToString(&loadInfo);
			size_t length = loadInfo.size();

			s->Send(&length, sizeof(length));

			char info_cstr[length + 1];
			strncpy(info_cstr, loadInfo.c_str(), length);
			info_cstr[length] = '\0';

			s->Send(info_cstr, length);


			//sleep(SLEEP_TIME);
			//Collect load information
			//send to server
			//Sleep
		}
	}
	else{
		perror("Couldn't connect to load-server");
	}
}
